package com.example.neo4j.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.example.neo4j.pojo.node.User;
import com.example.neo4j.pojo.util.ResponseInfo;
import com.example.neo4j.repository.HobbyRepository;
import com.example.neo4j.repository.ShareRepository;
import com.example.neo4j.repository.UserRepository;
import com.example.neo4j.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.stream.Collector;
import java.util.stream.Collectors;


@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private HobbyRepository hobbyRepository;

    @Autowired
    private ShareRepository shareRepository;

    @Override
    public ResponseInfo unfollow(String follower, String following) {
        Long num = userRepository.deleteRelation(follower, following);
        if (num == 0) {
            return new ResponseInfo("fail", false, num);
        }
        return new ResponseInfo("success", true, num);
    }

    @Override
    public String recommendFriendsByFriend(HttpServletRequest request, Map<String, Object> map) {
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute("user");
        if (user == null) {
            return "login";
        }
        //朋友的朋友
        List<User> users = userRepository.recommendFriendsByFriend(user.getAccount());
        List<User> myfollowing = userRepository.getMyFollowing(user.getAccount());
        HashSet<User> res = new HashSet<>();
        for (User value : users) {
            if (value.getAccount().equals(user.getAccount()))
                continue;
            if (contains(myfollowing, value)) continue;
            res.add(value);
        }
        List<User> followMe = userRepository.getFollowMe(user.getAccount());
        map.put("myfollowing", CollectionUtils.isEmpty(myfollowing) ? 0 : myfollowing.size());
        map.put("follower", CollectionUtils.isEmpty(followMe) ? 0 : followMe.size());
        map.put("recommends", res);
        map.put("user", user);
        map.put("index", "朋友推荐");
        map.put("title", "可能认识的人");
        return "userlist";
    }

    @Override
    public ResponseInfo praiseShare(String account, Integer shareid) {
        Integer number = userRepository.isPraised(shareid, account);
        if (number > 0) {
            Long praise_number = userRepository.getPraisedNumber(shareid);
            return new ResponseInfo("check", true, praise_number);
        }
        Long relationshipId = userRepository.praisedIt(account, shareid);
        Long praise_number = userRepository.getPraisedNumber(shareid);
        return new ResponseInfo(relationshipId != null ? "success" : "fail", relationshipId != null, praise_number);
    }

    @Override
    public ResponseInfo unpraiseShare(String account, Integer shareid) {
        Integer affect_rowes=userRepository.canclepraised(account,shareid);
        Long praise_number=userRepository.getPraisedNumber(shareid);
        return new ResponseInfo(affect_rowes>0?"success":"fail",affect_rowes>0,praise_number);
    }

    @Override
    public String index() {
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute("user");
        if (user == null) {
            return "login";
        } else {
            return "redirect:/content";
        }
    }

    @Override
    public String addUser(String account, String password, Integer age, String gender, String email, String address, String nickname, Map<String, Object> map) {
        User user = userRepository.getUserByAccount(account);
        if (user != null) {
            map.put("msg", "该账号已经存在，请登录");
            return "login";
        }
        user = userRepository.adduser(account, password, nickname, age, gender, email, address);
        if (user != null) {
            return "redirect:/content";
        }
        map.put("msg", "注册失败，请联系管理员");
        return "register";
    }

    @Override
    public String content(HttpServletRequest request, Map<String, Object> paramMap) {
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute("user");
        if (user == null) {
            return "login";
        }

        //我的关注
        List<User> myFollowing = userRepository.getMyFollowing(user.getAccount());
        //关注我的
        List<User> followMe = userRepository.getFollowMe(user.getAccount());

        //相同兴趣
        List<User> sameHobbyUsers = userRepository.getSameHobbyUsers(user.getAccount());
        paramMap.put("byfriend", new HashSet<>());
        paramMap.put("byshare", new HashSet<>());
        paramMap.put("byhobby", sameHobbyUsers);

        paramMap.put("shares", shareRepository.getFriendShares(user.getAccount()));
        paramMap.put("user", user);
        paramMap.put("myfollowing", ObjectUtil.isEmpty(myFollowing) ? 0 : myFollowing.size());
        paramMap.put("follower", ObjectUtil.isEmpty(followMe) ? 0 : followMe.size());
        return "content";
    }

    @Override
    public String index(String account, String password, Map<String, Object> paramMap, HttpServletRequest request) {
        User user = userRepository.checkUser(account, password);
        if (user == null) {
            paramMap.put("msg", "用户名或者密码错误");
            return "login";
        } else {
            HttpSession session = request.getSession();
            session.setAttribute("user", user);
            return "redirect:content";
        }
    }

    @Override
    public ResponseInfo likeHobby(String account, Long hobbyid) {
        Integer num = userRepository.likeHobby(account, hobbyid);
        return new ResponseInfo(num == 1 ? "添加兴趣成功" : "添加兴趣失败", num == 1, num);
    }

    @Override
    public String logout(HttpServletRequest request) {
        HttpSession session = request.getSession();
        session.removeAttribute("user");
        return "login";
    }

    @Override
    public String recommendFriendsByHobby(HttpServletRequest request, Map<String, Object> map) {
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute("user");
        if (user == null) {
            return "login";
        }
        //跟我有共同爱好 且我未关注的人
        List<User> users = userRepository.getSameHobbyUsers(user.getAccount());
        List<User> userList = userRepository.getMyFollowing(user.getAccount()) == null ? new ArrayList<>() : userRepository.getMyFollowing(user.getAccount());
        List<Long> ids = userList.parallelStream().map(User::getId).collect(Collectors.toList());
        HashSet<User> res = new HashSet<>();
        users.forEach(u -> {
            if (!ids.contains(u.getId())) {
                res.add(u);
            }
        });

        List<User> myFuns = userRepository.getFollowMe(user.getAccount());
        map.put("myfollowing", userList.size());
        map.put("follower", myFuns.size());
        map.put("recommends", res);
        map.put("user", user);
        map.put("index", "朋友推荐");
        map.put("title", "趣味相投的人");
        map.put("reverse", false);
        return "userlist";
    }

    @Override
    public ResponseInfo unlikeHobby(String account, Long hobbyid) {
        Integer num = userRepository.unlikeHobby(account, hobbyid);
        return new ResponseInfo(num > 0 ? "删除兴趣成功" : "删除兴趣失败", num > 0, num);
    }

    @Override
    public ResponseInfo followIt(String follower, String following) {
        Long id = userRepository.createFollow(follower, following);
        if (id != null) {
            return new ResponseInfo("success", true, id);
        }
        return new ResponseInfo("fail", false, null);
    }

    @Override
    public String getMyFollowing(HttpServletRequest request, Map<String, Object> map) {
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute("user");
        if (user == null) {
            return "login";
        }
        List<User> following = userRepository.getMyFollowing(user.getAccount());
        List<User> followMe = userRepository.getFollowMe(user.getAccount());
        map.put("myfollowing", ObjectUtil.isEmpty(following) ? 0 : following.size());
        map.put("follower", ObjectUtil.isEmpty(followMe) ? 0 : followMe.size());
        map.put("recommends", following);
        map.put("user", user);
        map.put("title", "我关注的人");
        map.put("index", "首页");
        return "myfollowing";
    }

    @Override
    public String getFans(HttpServletRequest request, Map<String, Object> map) {
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute("user");
        if (user == null) {
            return "login";
        }
        List<User> follower = userRepository.getFollowMe(user.getAccount());
        List<User> myfollowing = userRepository.getMyFollowing(user.getAccount());
        HashSet<User> recommends = new HashSet<>();
        HashSet<User> subFollowing = new HashSet<>();
        for (User value : follower) {
            if (contains(myfollowing, value)) {
                subFollowing.add(value);
                continue;
            }
            recommends.add(value);
        }

        map.put("myfollowing", ObjectUtil.isEmpty(myfollowing) ? 0 : myfollowing.size());
        map.put("follower", ObjectUtil.isEmpty(follower) ? 0 : follower.size());
        map.put("recommends", recommends);
        map.put("mystar", subFollowing);
        map.put("user", user);
        map.put("title", "关注我的人");
        map.put("index", "首页");
        map.put("hascategory", true);
        return "userlist";
    }

    public static boolean contains(List<User> arr, User target) {
        for (User user : arr) {
            if (user.getId().equals(target.getId()))
                return true;
        }
        return false;
    }
}
